home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pnm / pnmarith.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-10  |  4.8 KB  |  196 lines

  1. /* pnmarith.c - perform arithmetic on two portable anymaps
  2. **
  3. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pnm.h"
  14.  
  15. void
  16. main( argc, argv )
  17.     int argc;
  18.     char* argv[];
  19.     {
  20.     FILE* ifp1;
  21.     FILE* ifp2;
  22.     register xel* xelrow1;
  23.     register xel* xelrow2;
  24.     register xel* x1P;
  25.     register xel* x2P;
  26.     xelval maxval1, maxval2, maxval3;
  27.     int argn, rows1, cols1, format1, rows2, cols2, format2, format3, row, col;
  28.     char function;
  29.     char* usage = "-add|-subtract|-multiply pnmfile1 pnmfile2";
  30.  
  31.     pnm_init( &argc, argv );
  32.  
  33.     argn = 1;
  34.     function = ' ';
  35.  
  36.     /* Check for flags. */
  37.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  38.     {
  39.     if ( pm_keymatch( argv[argn], "-add", 2 ) )
  40.         function = '+';
  41.     else if ( pm_keymatch( argv[argn], "-subtract", 2 ) )
  42.         function = '-';
  43.     else if ( pm_keymatch( argv[argn], "-multiply", 2 ) )
  44.         function = '*';
  45.     else
  46.         pm_usage( usage );
  47.     ++argn;
  48.     }
  49.  
  50.     if ( function == ' ' )
  51.     pm_usage( usage );
  52.  
  53.     if ( argn == argc )
  54.     pm_usage( usage );
  55.     ifp1 = pm_openr( argv[argn] );
  56.     ++argn;
  57.  
  58.     if ( argn == argc )
  59.     pm_usage( usage );
  60.     ifp2 = pm_openr( argv[argn] );
  61.     ++argn;
  62.  
  63.     if ( argn != argc )
  64.     pm_usage( usage );
  65.  
  66.     pnm_readpnminit( ifp1, &cols1, &rows1, &maxval1, &format1 );
  67.     xelrow1 = pnm_allocrow( cols1 );
  68.     pnm_readpnminit( ifp2, &cols2, &rows2, &maxval2, &format2 );
  69.     if ( cols2 != cols1 || rows2 != rows1 )
  70.     pm_error(
  71.         "the two anymaps must be the same width and height" );
  72.     xelrow2 = pnm_allocrow( cols1 );
  73.  
  74.     maxval3 = max( maxval1, maxval2 );
  75.     format3 = max( PNM_FORMAT_TYPE(format1), PNM_FORMAT_TYPE(format2) );
  76.     if ( PNM_FORMAT_TYPE(format1) != format3 ||
  77.      PNM_FORMAT_TYPE(format2) != format3 )
  78.     {
  79.     switch ( PNM_FORMAT_TYPE(format3) )
  80.         {
  81.         case PPM_TYPE:
  82.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  83.         pm_message( "promoting first file to PPM" );
  84.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  85.         pm_message( "promoting second file to PPM" );
  86.         break;
  87.         case PGM_TYPE:
  88.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  89.         pm_message( "promoting first file to PGM" );
  90.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  91.         pm_message( "promoting second file to PGM" );
  92.         break;
  93.         }
  94.     }
  95.  
  96.     pnm_writepnminit( stdout, cols1, rows1, maxval3, format3, 0 );
  97.     for ( row = 0; row < rows1; ++row )
  98.     {
  99.     pnm_readpnmrow( ifp1, xelrow1, cols1, maxval1, format1 );
  100.     if ( maxval1 != maxval3 || PNM_FORMAT_TYPE(format1) != format3 )
  101.         pnm_promoteformatrow(
  102.         xelrow1, cols1, maxval1, format1, maxval3, format3 );
  103.  
  104.     pnm_readpnmrow( ifp2, xelrow2, cols1, maxval2, format2 );
  105.     if ( maxval2 != maxval3 || PNM_FORMAT_TYPE(format2) != format3 )
  106.         pnm_promoteformatrow(
  107.         xelrow2, cols1, maxval2, format2, maxval3, format3 );
  108.  
  109.         for ( col = 0, x1P = xelrow1, x2P = xelrow2;
  110.           col < cols1; ++col, ++x1P, ++x2P )
  111.         {
  112.         switch ( PNM_FORMAT_TYPE(format3) )
  113.         {
  114.         case PPM_TYPE:
  115.         {
  116.         int r1, g1, b1, r2, g2, b2;
  117.  
  118.         r1 = PPM_GETR( *x1P );
  119.         g1 = PPM_GETG( *x1P );
  120.         b1 = PPM_GETB( *x1P );
  121.         r2 = PPM_GETR( *x2P );
  122.         g2 = PPM_GETG( *x2P );
  123.         b2 = PPM_GETB( *x2P );
  124.         switch ( function )
  125.             {
  126.             case '+':
  127.             r1 += r2;
  128.             g1 += g2;
  129.             b1 += b2;
  130.             break;
  131.  
  132.             case '-':
  133.             r1 -= r2;
  134.             g1 -= g2;
  135.             b1 -= b2;
  136.             break;
  137.  
  138.             case '*':
  139.             r1 = r1 * r2 / maxval3;
  140.             g1 = g1 * g2 / maxval3;
  141.             b1 = b1 * b2 / maxval3;
  142.             break;
  143.  
  144.             default:
  145.             pm_error( "can't happen" );
  146.             }
  147.         if ( r1 < 0 ) r1 = 0;
  148.         else if ( r1 > maxval3 ) r1 = maxval3;
  149.         if ( g1 < 0 ) g1 = 0;
  150.         else if ( g1 > maxval3 ) g1 = maxval3;
  151.         if ( b1 < 0 ) b1 = 0;
  152.         else if ( b1 > maxval3 ) b1 = maxval3;
  153.         PPM_ASSIGN( *x1P, r1, g1, b1 );
  154.         }
  155.         break;
  156.  
  157.         default:
  158.         {
  159.         int g1, g2;
  160.  
  161.         g1 = PNM_GET1( *x1P );
  162.         g2 = PNM_GET1( *x2P );
  163.         switch ( function )
  164.             {
  165.             case '+':
  166.             g1 += g2;
  167.             break;
  168.  
  169.             case '-':
  170.             g1 -= g2;
  171.             break;
  172.  
  173.             case '*':
  174.             g1 = g1 * g2 / maxval3;
  175.             break;
  176.  
  177.             default:
  178.             pm_error( "can't happen" );
  179.             }
  180.         if ( g1 < 0 ) g1 = 0;
  181.         else if ( g1 > maxval3 ) g1 = maxval3;
  182.         PNM_ASSIGN1( *x1P, g1 );
  183.         }
  184.         break;
  185.         }
  186.         }
  187.     pnm_writepnmrow( stdout, xelrow1, cols1, maxval3, format3, 0 );
  188.     }
  189.  
  190.     pm_close( ifp1 );
  191.     pm_close( ifp2 );
  192.     pm_close( stdout );
  193.  
  194.     exit( 0 );
  195.     }
  196.